/*      */ package com.zimbra.cs.index;
/*      */ 
/*      */ import com.google.common.base.Joiner;
/*      */ import com.google.common.base.Objects;
/*      */ import com.google.common.base.Splitter;
/*      */ import com.google.common.base.Strings;
/*      */ import com.google.common.collect.ImmutableMap;
/*      */ import com.google.common.collect.ImmutableMap.Builder;
/*      */ import com.zimbra.common.calendar.ICalTimeZone;
/*      */ import com.zimbra.common.calendar.WellKnownTimeZones;
/*      */ import com.zimbra.common.localconfig.DebugConfig;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.soap.Element;
/*      */ import com.zimbra.common.soap.Element.Disposition;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.cs.account.Server;
/*      */ import com.zimbra.cs.mailbox.MailItem;
/*      */ import com.zimbra.cs.mailbox.MailItem.Type;
/*      */ import com.zimbra.cs.mailbox.MailServiceException;
/*      */ import com.zimbra.cs.service.mail.CalendarUtils;
/*      */ import com.zimbra.cs.service.mail.ToXML.OutputParticipants;
/*      */ import com.zimbra.cs.service.util.ItemId;
/*      */ import com.zimbra.soap.ZimbraSoapContext;
/*      */ import com.zimbra.soap.base.CalTZInfoInterface;
/*      */ import com.zimbra.soap.base.SearchParameters;
/*      */ import com.zimbra.soap.mail.type.MailSearchParams;
/*      */ import com.zimbra.soap.type.AttributeName;
/*      */ import com.zimbra.soap.type.CursorInfo;
/*      */ import com.zimbra.soap.type.WantRecipsSetting;
/*      */ import com.zimbra.soap.type.ZmBoolean;
/*      */ import java.util.ArrayList;
/*      */ import java.util.EnumSet;
/*      */ import java.util.HashSet;
/*      */ import java.util.List;
/*      */ import java.util.Locale;
/*      */ import java.util.Map;
/*      */ import java.util.Set;
/*      */ import java.util.TimeZone;
/*      */ import java.util.regex.Matcher;
/*      */ import java.util.regex.Pattern;
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ public final class SearchParams
/*      */   implements Cloneable
/*      */ {
/*      */   private static final int DEFAULT_LIMIT = 10;
/*      */   private static final int MAX_OFFSET = 10000000;
/*      */   private static final int MAX_PARSABLE_LIMIT = 1000;
/*      */   private static final int MAX_LIMIT = 10000000;
/*   72 */   private static final Pattern LOCALE_PATTERN = Pattern.compile("([a-zA-Z]{2})(?:[-_]([a-zA-Z]{2})([-_](.+))?)?");
/*      */   
/*      */   private ZimbraSoapContext requestContext;
/*      */   private int hopCount;
/*      */   private String defaultField;
/*      */   
/*      */   public SearchParams()
/*      */   {
/*   80 */     this.hopCount = 0;
/*   81 */     this.defaultField = "content:";
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*   86 */     this.markRead = false;
/*      */     
/*   88 */     this.wantHtml = false;
/*   89 */     this.wantExpandGroupInfo = false;
/*   90 */     this.neuterImages = false;
/*      */     
/*      */ 
/*   93 */     this.calItemExpandStart = -1L;
/*   94 */     this.calItemExpandEnd = -1L;
/*   95 */     this.inDumpster = false;
/*   96 */     this.fullConversation = false;
/*      */     
/*      */ 
/*   99 */     this.includeTagDeleted = false;
/*      */     
/*  101 */     this.includeTagMuted = true;
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  110 */     this.types = EnumSet.noneOf(MailItem.Type.class);
/*      */     
/*  112 */     this.prefetch = true;
/*  113 */     this.fetch = Fetch.NORMAL;
/*  114 */     this.quick = false;
/*      */   }
/*      */   
/*  117 */   public boolean isQuick() { return this.quick; }
/*      */   
/*      */   public void setQuick(boolean value)
/*      */   {
/*  121 */     this.quick = value;
/*      */   }
/*      */   
/*      */   public ZimbraSoapContext getRequestContext() {
/*  125 */     return this.requestContext;
/*      */   }
/*      */   
/*      */   public int getHopCount() {
/*  129 */     return this.hopCount;
/*      */   }
/*      */   
/*      */   public long getCalItemExpandStart() {
/*  133 */     return this.calItemExpandStart;
/*      */   }
/*      */   
/*      */   public long getCalItemExpandEnd() {
/*  137 */     return this.calItemExpandEnd;
/*      */   }
/*      */   
/*      */   public String getQueryString() {
/*  141 */     return this.queryString;
/*      */   }
/*      */   
/*      */   public Set<MailItem.Type> getTypes() {
/*  145 */     return this.types;
/*      */   }
/*      */   
/*      */   public SortBy getSortBy() {
/*  149 */     return this.sortBy;
/*      */   }
/*      */   
/*      */   public ExpandResults getInlineRule() {
/*  153 */     return this.inlineRule;
/*      */   }
/*      */   
/*      */   public boolean getMarkRead() {
/*  157 */     return this.markRead;
/*      */   }
/*      */   
/*      */   public int getMaxInlinedLength() {
/*  161 */     return this.maxInlinedLength;
/*      */   }
/*      */   
/*      */   public boolean getWantHtml() {
/*  165 */     return this.wantHtml;
/*      */   }
/*      */   
/*      */   public boolean getWantExpandGroupInfo() {
/*  169 */     return this.wantExpandGroupInfo;
/*      */   }
/*      */   
/*      */   public boolean getNeuterImages() {
/*  173 */     return this.neuterImages;
/*      */   }
/*      */   
/*      */   public Set<String> getInlinedHeaders() {
/*  177 */     return this.inlinedHeaders;
/*      */   }
/*      */   
/*      */   public ToXML.OutputParticipants getWantRecipients() {
/*  181 */     return this.recipients;
/*      */   }
/*      */   
/*      */   public TimeZone getTimeZone() {
/*  185 */     return this.timezone;
/*      */   }
/*      */   
/*      */   public Locale getLocale() {
/*  189 */     return this.locale;
/*      */   }
/*      */   
/*      */   public boolean getPrefetch() {
/*  193 */     return this.prefetch;
/*      */   }
/*      */   
/*      */   public Fetch getFetchMode() {
/*  197 */     return this.fetch;
/*      */   }
/*      */   
/*      */   public String getDefaultField() {
/*  201 */     return this.defaultField;
/*      */   }
/*      */   
/*      */   public final boolean getIncludeTagDeleted() {
/*  205 */     return this.includeTagDeleted;
/*      */   }
/*      */   
/*      */   public final boolean getIncludeTagMuted() {
/*  209 */     return this.includeTagMuted;
/*      */   }
/*      */   
/*      */   public Set<TaskHit.Status> getAllowableTaskStatuses() {
/*  213 */     return this.allowableTaskStatuses;
/*      */   }
/*      */   
/*      */   public int getLimit() {
/*  217 */     return this.limit;
/*      */   }
/*      */   
/*      */   public int getOffset() {
/*  221 */     return this.offset;
/*      */   }
/*      */   
/*      */   public boolean inDumpster() {
/*  225 */     return this.inDumpster;
/*      */   }
/*      */   
/*      */   public void setInDumpster(boolean value) {
/*  229 */     this.inDumpster = value;
/*      */   }
/*      */   
/*      */   public boolean fullConversation() {
/*  233 */     return this.fullConversation;
/*      */   }
/*      */   
/*      */   public void setFullConversation(boolean value) {
/*  237 */     this.fullConversation = value;
/*      */   }
/*      */   
/*      */   public void setHopCount(int value) {
/*  241 */     this.hopCount = value;
/*      */   }
/*      */   
/*      */   public void setQueryString(String value) {
/*  245 */     this.queryString = value;
/*      */   }
/*      */   
/*      */   public void setOffset(int value) {
/*  249 */     this.offset = Math.min(value, 10000000);
/*      */   }
/*      */   
/*      */   public void setLimit(int value) {
/*  253 */     this.limit = Math.min(value, 10000000);
/*      */   }
/*      */   
/*      */   public void setDefaultField(String value) {
/*  257 */     if (!value.endsWith(":")) {
/*  258 */       value = value + ':';
/*      */     }
/*  260 */     this.defaultField = value;
/*      */   }
/*      */   
/*      */   public final void setIncludeTagDeleted(boolean value) {
/*  264 */     this.includeTagDeleted = value;
/*      */   }
/*      */   
/*      */   public final void setIncludeTagMuted(boolean value) {
/*  268 */     this.includeTagMuted = value;
/*      */   }
/*      */   
/*      */   public void setAllowableTaskStatuses(Set<TaskHit.Status> value) {
/*  272 */     this.allowableTaskStatuses = value;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public void setCalItemExpandStart(long value)
/*      */   {
/*  279 */     this.calItemExpandStart = value;
/*      */   }
/*      */   
/*      */   private String queryString;
/*      */   private int offset;
/*      */   private int limit;
/*      */   private ExpandResults inlineRule;
/*  286 */   public void setCalItemExpandEnd(long value) { this.calItemExpandEnd = value; }
/*      */   
/*      */   private boolean markRead;
/*      */   private int maxInlinedLength;
/*      */   private boolean wantHtml;
/*      */   private boolean wantExpandGroupInfo;
/*      */   private boolean neuterImages;
/*      */   private Set<String> inlinedHeaders;
/*      */   private ToXML.OutputParticipants recipients;
/*  295 */   public void setChunkSize(int value) { setLimit(value + this.offset); }
/*      */   
/*      */   public void setTypes(String value) throws ServiceException
/*      */   {
/*      */     try {
/*  300 */       setTypes(MailItem.Type.setOf(value));
/*      */     } catch (IllegalArgumentException e) {
/*  302 */       throw MailServiceException.INVALID_TYPE(e.getMessage());
/*      */     }
/*      */   }
/*      */   
/*      */   public void setTypes(Set<MailItem.Type> value) {
/*  307 */     this.types = value;
/*  308 */     checkForLocalizedContactSearch();
/*      */   }
/*      */   
/*      */   private boolean isSystemDefaultLocale() {
/*  312 */     if (this.locale == null) {
/*  313 */       return true;
/*      */     }
/*      */     
/*  316 */     return this.locale.equals(Locale.getDefault());
/*      */   }
/*      */   
/*      */   private void checkForLocalizedContactSearch() {
/*  320 */     if (DebugConfig.enableContactLocalizedSort)
/*      */     {
/*      */ 
/*  323 */       if ((this.types.size() == 1) && (this.types.contains(MailItem.Type.CONTACT)) && (!isSystemDefaultLocale()) && 
/*  324 */         (this.locale != null) && 
/*  325 */         (this.sortBy != null)) {
/*  326 */         switch (this.sortBy) {
/*      */         case NAME_ASC: 
/*  328 */           this.sortBy = SortBy.NAME_LOCALIZED_ASC;
/*  329 */           break;
/*      */         case NAME_DESC: 
/*  331 */           this.sortBy = SortBy.NAME_LOCALIZED_DESC;
/*      */         }
/*      */         
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public void setSortBy(SortBy value)
/*      */   {
/*  341 */     this.sortBy = value;
/*  342 */     checkForLocalizedContactSearch();
/*      */   }
/*      */   
/*      */   public void setSortBy(String value) {
/*  346 */     SortBy sort = SortBy.of(value);
/*  347 */     if (sort == null) {
/*  348 */       sort = SortBy.DATE_DESC;
/*      */     }
/*  350 */     setSortBy(sort);
/*      */   }
/*      */   
/*      */   public void setInlineRule(ExpandResults value) {
/*  354 */     this.inlineRule = value;
/*      */   }
/*      */   
/*      */   public void setMarkRead(boolean value) {
/*  358 */     this.markRead = value;
/*      */   }
/*      */   
/*      */   public void setMaxInlinedLength(int value) {
/*  362 */     this.maxInlinedLength = value;
/*      */   }
/*      */   
/*      */   public void setWantHtml(boolean value) {
/*  366 */     this.wantHtml = value;
/*      */   }
/*      */   
/*      */   public void setWantExpandGroupInfo(boolean value) {
/*  370 */     this.wantExpandGroupInfo = value;
/*      */   }
/*      */   
/*      */   public void setNeuterImages(boolean value) {
/*  374 */     this.neuterImages = value;
/*      */   }
/*      */   
/*      */   public void addInlinedHeader(String value) {
/*  378 */     if (this.inlinedHeaders == null) {
/*  379 */       this.inlinedHeaders = new HashSet();
/*      */     }
/*  381 */     this.inlinedHeaders.add(value);
/*      */   }
/*      */   
/*      */   public void setWantRecipients(WantRecipsSetting jaxbValue) {
/*  385 */     this.recipients = ToXML.OutputParticipants.fromJaxb(jaxbValue);
/*      */   }
/*      */   
/*      */   public void setWantRecipients(Integer value) {
/*  389 */     if (value == null) {
/*  390 */       this.recipients = ToXML.OutputParticipants.PUT_SENDERS;
/*  391 */     } else if (2 == value.intValue()) {
/*  392 */       this.recipients = ToXML.OutputParticipants.PUT_BOTH;
/*  393 */     } else if (1 == value.intValue()) {
/*  394 */       this.recipients = ToXML.OutputParticipants.PUT_RECIPIENTS;
/*      */     } else {
/*  396 */       this.recipients = ToXML.OutputParticipants.PUT_SENDERS;
/*      */     }
/*      */   }
/*      */   
/*      */   public void setTimeZone(TimeZone value) {
/*  401 */     this.timezone = value;
/*      */   }
/*      */   
/*      */   public void setLocale(Locale value) {
/*  405 */     this.locale = value;
/*  406 */     checkForLocalizedContactSearch();
/*      */   }
/*      */   
/*      */   public Cursor getCursor() {
/*  410 */     return this.cursor;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public void setCursor(Cursor value)
/*      */   {
/*  417 */     this.cursor = value;
/*      */   }
/*      */   
/*      */   public void setPrefetch(boolean value) {
/*  421 */     this.prefetch = value;
/*      */   }
/*      */   
/*      */   public void setFetchMode(Fetch value) {
/*  425 */     this.fetch = value;
/*      */   }
/*      */   
/*      */   private long calItemExpandStart;
/*      */   private long calItemExpandEnd;
/*      */   private boolean inDumpster;
/*      */   private boolean fullConversation;
/*      */   private boolean includeTagDeleted;
/*      */   private boolean includeTagMuted;
/*      */   private Set<TaskHit.Status> allowableTaskStatuses;
/*      */   
/*      */   public void encodeParams(Element el)
/*      */   {
/*  438 */     if (this.allowableTaskStatuses != null) {
/*  439 */       el.addAttribute("allowableTaskStatus", Joiner.on(',').join(this.allowableTaskStatuses));
/*      */     }
/*  441 */     el.addAttribute("includeTagDeleted", getIncludeTagDeleted());
/*  442 */     el.addAttribute("includeTagMuted", getIncludeTagMuted());
/*  443 */     el.addAttribute("calExpandInstStart", getCalItemExpandStart());
/*  444 */     el.addAttribute("calExpandInstEnd", getCalItemExpandEnd());
/*  445 */     el.addAttribute("query", getQueryString(), Element.Disposition.CONTENT);
/*  446 */     el.addAttribute("types", MailItem.Type.toString(this.types));
/*  447 */     if (this.sortBy != null) {
/*  448 */       if (SortBy.NAME_LOCALIZED_ASC.equals(this.sortBy)) {
/*  449 */         el.addAttribute("sortBy", SortBy.NAME_ASC.toString());
/*  450 */       } else if (SortBy.NAME_LOCALIZED_DESC.equals(this.sortBy)) {
/*  451 */         el.addAttribute("sortBy", SortBy.NAME_DESC.toString());
/*      */       } else {
/*  453 */         el.addAttribute("sortBy", this.sortBy.toString());
/*      */       }
/*      */     }
/*  456 */     if (getInlineRule() != null) {
/*  457 */       el.addAttribute("fetch", getInlineRule().toString());
/*      */     }
/*  459 */     el.addAttribute("read", getMarkRead());
/*  460 */     el.addAttribute("max", getMaxInlinedLength());
/*  461 */     el.addAttribute("html", getWantHtml());
/*  462 */     el.addAttribute("needExp", getWantExpandGroupInfo());
/*  463 */     el.addAttribute("neuter", getNeuterImages());
/*  464 */     if (getInlinedHeaders() != null) {
/*  465 */       for (String name : getInlinedHeaders()) {
/*  466 */         el.addElement("header").addAttribute("n", name);
/*      */       }
/*      */     }
/*  469 */     if (this.recipients != null) {
/*  470 */       el.addAttribute("recip", this.recipients.getIntValue());
/*      */     }
/*      */     
/*  473 */     if (getLocale() != null) {
/*  474 */       el.addElement("locale").setText(getLocale().toString());
/*      */     }
/*  476 */     el.addAttribute("prefetch", getPrefetch());
/*  477 */     el.addAttribute("resultMode", getFetchMode().name());
/*  478 */     el.addAttribute("field", getDefaultField());
/*      */     
/*  480 */     el.addAttribute("limit", this.limit);
/*  481 */     el.addAttribute("offset", this.offset);
/*      */     
/*  483 */     el.addAttribute("inDumpster", this.inDumpster);
/*  484 */     if (this.quick) {
/*  485 */       el.addAttribute("quick", this.quick);
/*      */     }
/*      */   }
/*      */   
/*      */   private TimeZone timezone;
/*      */   private Locale locale;
/*      */   private SortBy sortBy;
/*      */   private Set<MailItem.Type> types;
/*      */   private Cursor cursor;
/*      */   private boolean prefetch;
/*      */   private Fetch fetch;
/*      */   private boolean quick;
/*      */   public static SearchParams parse(SearchParameters soapParams, ZimbraSoapContext zsc, String defaultQueryStr)
/*      */     throws ServiceException
/*      */   {
/*  500 */     SearchParams params = new SearchParams();
/*      */     
/*  502 */     params.requestContext = zsc;
/*  503 */     params.setHopCount(zsc.getHopCount());
/*  504 */     params.setCalItemExpandStart(((Long)Objects.firstNonNull(soapParams.getCalItemExpandStart(), Long.valueOf(-1L))).longValue());
/*  505 */     params.setCalItemExpandEnd(((Long)Objects.firstNonNull(soapParams.getCalItemExpandEnd(), Long.valueOf(-1L))).longValue());
/*  506 */     String query = soapParams.getQuery() == null ? defaultQueryStr : soapParams.getQuery();
/*  507 */     if (query == null) {
/*  508 */       throw ServiceException.INVALID_REQUEST("no query submitted and no default query found", null);
/*      */     }
/*  510 */     params.setQueryString(query);
/*  511 */     params.setInDumpster(((Boolean)Objects.firstNonNull(soapParams.getInDumpster(), Boolean.valueOf(false))).booleanValue());
/*  512 */     params.setQuick(((Boolean)Objects.firstNonNull(soapParams.getQuick(), Boolean.valueOf(false))).booleanValue());
/*  513 */     String types = soapParams.getSearchTypes() == null ? soapParams.getGroupBy() : soapParams.getSearchTypes();
/*  514 */     if (Strings.isNullOrEmpty(types)) {
/*  515 */       params.setTypes(EnumSet.of(params.isQuick() ? MailItem.Type.MESSAGE : MailItem.Type.CONVERSATION));
/*      */     } else {
/*  517 */       params.setTypes(types);
/*      */     }
/*  519 */     params.setSortBy(soapParams.getSortBy());
/*      */     
/*  521 */     params.setIncludeTagDeleted(((Boolean)Objects.firstNonNull(soapParams.getIncludeTagDeleted(), Boolean.valueOf(false))).booleanValue());
/*  522 */     params.setIncludeTagMuted(((Boolean)Objects.firstNonNull(soapParams.getIncludeTagMuted(), Boolean.valueOf(true))).booleanValue());
/*  523 */     String allowableTasks = soapParams.getAllowableTaskStatus();
/*  524 */     if (allowableTasks != null) {
/*  525 */       params.allowableTaskStatuses = new HashSet();
/*  526 */       for (String task : Splitter.on(',').split(allowableTasks)) {
/*      */         try {
/*  528 */           TaskHit.Status status = TaskHit.Status.valueOf(task.toUpperCase());
/*  529 */           params.allowableTaskStatuses.add(status);
/*      */         } catch (IllegalArgumentException e) {
/*  531 */           ZimbraLog.index.debug("Skipping unknown task completion status: %s", new Object[] { task });
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*  536 */     params.setInlineRule(ExpandResults.valueOf(soapParams.getFetch(), zsc));
/*  537 */     if (params.getInlineRule() != ExpandResults.NONE) {
/*  538 */       params.setMarkRead(((Boolean)Objects.firstNonNull(soapParams.getMarkRead(), Boolean.valueOf(false))).booleanValue());
/*  539 */       params.setMaxInlinedLength(((Integer)Objects.firstNonNull(soapParams.getMaxInlinedLength(), Integer.valueOf(-1))).intValue());
/*  540 */       params.setWantHtml(((Boolean)Objects.firstNonNull(soapParams.getWantHtml(), Boolean.valueOf(false))).booleanValue());
/*  541 */       params.setWantExpandGroupInfo(((Boolean)Objects.firstNonNull(soapParams.getNeedCanExpand(), Boolean.valueOf(false))).booleanValue());
/*  542 */       params.setNeuterImages(((Boolean)Objects.firstNonNull(soapParams.getNeuterImages(), Boolean.valueOf(true))).booleanValue());
/*  543 */       for (AttributeName hdr : soapParams.getHeaders()) {
/*  544 */         params.addInlinedHeader(hdr.getName());
/*      */       }
/*      */     }
/*  547 */     params.setWantRecipients(soapParams.getWantRecipients());
/*      */     
/*  549 */     CalTZInfoInterface calTZ = soapParams.getCalTz();
/*  550 */     if (calTZ != null) {
/*  551 */       params.setTimeZone(parseTimeZonePart(calTZ));
/*      */     }
/*      */     
/*  554 */     String locale = soapParams.getLocale();
/*  555 */     if (locale != null) {
/*  556 */       params.setLocale(parseLocale(locale));
/*      */     }
/*      */     
/*  559 */     params.setPrefetch(((Boolean)Objects.firstNonNull(soapParams.getPrefetch(), Boolean.valueOf(true))).booleanValue());
/*  560 */     String resultMode = soapParams.getResultMode();
/*  561 */     if (!Strings.isNullOrEmpty(resultMode)) {
/*      */       try {
/*  563 */         params.setFetchMode(Fetch.valueOf(resultMode.toUpperCase()));
/*      */       } catch (IllegalArgumentException e) {
/*  565 */         throw ServiceException.INVALID_REQUEST(String.format("Invalid %s \"%s\"", new Object[] { "resultMode", resultMode }), e);
/*      */       }
/*      */     }
/*      */     
/*      */ 
/*  570 */     String field = params.getDefaultField();
/*  571 */     if (field != null) {
/*  572 */       params.setDefaultField(field);
/*      */     }
/*      */     
/*  575 */     params.setLimit(parseLimit(soapParams.getLimit()));
/*  576 */     params.setOffset(((Integer)Objects.firstNonNull(soapParams.getOffset(), Integer.valueOf(0))).intValue());
/*      */     
/*  578 */     CursorInfo cursor = soapParams.getCursor();
/*  579 */     if (cursor != null) {
/*  580 */       params.parseCursor(cursor, zsc.getRequestedAccountId());
/*      */     }
/*      */     
/*  583 */     if ((soapParams instanceof MailSearchParams)) {
/*  584 */       MailSearchParams mailParams = (MailSearchParams)soapParams;
/*  585 */       params.setFullConversation(ZmBoolean.toBool(mailParams.getFullConversation(), false));
/*      */     }
/*  587 */     return params;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static SearchParams parse(Element request, ZimbraSoapContext zsc, String defaultQueryStr)
/*      */     throws ServiceException
/*      */   {
/*  600 */     SearchParams params = new SearchParams();
/*      */     
/*  602 */     params.requestContext = zsc;
/*  603 */     params.setHopCount(zsc.getHopCount());
/*  604 */     params.setCalItemExpandStart(request.getAttributeLong("calExpandInstStart", -1L));
/*  605 */     params.setCalItemExpandEnd(request.getAttributeLong("calExpandInstEnd", -1L));
/*  606 */     String query = request.getAttribute("query", defaultQueryStr);
/*  607 */     if (query == null) {
/*  608 */       throw ServiceException.INVALID_REQUEST("no query submitted and no default query found", null);
/*      */     }
/*  610 */     params.setQueryString(query);
/*  611 */     params.setInDumpster(request.getAttributeBool("inDumpster", false));
/*  612 */     params.setQuick(request.getAttributeBool("quick", false));
/*  613 */     String types = request.getAttribute("types", request.getAttribute("groupBy", null));
/*  614 */     if (Strings.isNullOrEmpty(types)) {
/*  615 */       params.setTypes(EnumSet.of(params.isQuick() ? MailItem.Type.MESSAGE : MailItem.Type.CONVERSATION));
/*      */     } else {
/*  617 */       params.setTypes(types);
/*      */     }
/*  619 */     params.setSortBy(request.getAttribute("sortBy", null));
/*      */     
/*  621 */     params.setIncludeTagDeleted(request.getAttributeBool("includeTagDeleted", false));
/*  622 */     params.setIncludeTagMuted(request.getAttributeBool("includeTagMuted", true));
/*  623 */     String allowableTasks = request.getAttribute("allowableTaskStatus", null);
/*  624 */     if (allowableTasks != null) {
/*  625 */       params.allowableTaskStatuses = new HashSet();
/*  626 */       for (String task : Splitter.on(',').split(allowableTasks)) {
/*      */         try {
/*  628 */           TaskHit.Status status = TaskHit.Status.valueOf(task.toUpperCase());
/*  629 */           params.allowableTaskStatuses.add(status);
/*      */         } catch (IllegalArgumentException e) {
/*  631 */           ZimbraLog.index.debug("Skipping unknown task completion status: %s", new Object[] { task });
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*  636 */     params.setInlineRule(ExpandResults.valueOf(request.getAttribute("fetch", null), zsc));
/*  637 */     if (params.getInlineRule() != ExpandResults.NONE) {
/*  638 */       params.setMarkRead(request.getAttributeBool("read", false));
/*  639 */       params.setMaxInlinedLength((int)request.getAttributeLong("max", -1L));
/*  640 */       params.setWantHtml(request.getAttributeBool("html", false));
/*  641 */       params.setWantExpandGroupInfo(request.getAttributeBool("needExp", false));
/*  642 */       params.setNeuterImages(request.getAttributeBool("neuter", true));
/*  643 */       for (Element elt : request.listElements("header")) {
/*  644 */         params.addInlinedHeader(elt.getAttribute("n"));
/*      */       }
/*      */     }
/*  647 */     params.setWantRecipients(Integer.valueOf((int)request.getAttributeLong("recip", 0L)));
/*      */     
/*  649 */     Element tz = request.getOptionalElement("tz");
/*  650 */     if (tz != null) {
/*  651 */       params.setTimeZone(parseTimeZonePart(tz));
/*      */     }
/*      */     
/*  654 */     Element locale = request.getOptionalElement("locale");
/*  655 */     if (locale != null) {
/*  656 */       params.setLocale(parseLocale(locale.getText()));
/*      */     }
/*      */     
/*  659 */     params.setPrefetch(request.getAttributeBool("prefetch", true));
/*  660 */     String fetch = request.getAttribute("resultMode", null);
/*  661 */     if (!Strings.isNullOrEmpty(fetch)) {
/*      */       try {
/*  663 */         params.setFetchMode(Fetch.valueOf(fetch.toUpperCase()));
/*      */       } catch (IllegalArgumentException e) {
/*  665 */         throw ServiceException.INVALID_REQUEST("Invalid resultMode", e);
/*      */       }
/*      */     }
/*      */     
/*  669 */     String field = request.getAttribute("field", null);
/*  670 */     if (field != null) {
/*  671 */       params.setDefaultField(field);
/*      */     }
/*      */     
/*  674 */     params.setLimit(parseLimit(request));
/*  675 */     params.setOffset(request.getAttributeInt("offset", 0));
/*      */     
/*  677 */     Element cursor = request.getOptionalElement("cursor");
/*  678 */     if (cursor != null) {
/*  679 */       params.parseCursor(cursor, zsc.getRequestedAccountId());
/*      */     }
/*      */     
/*  682 */     return params;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public void parseCursor(Element el, String acctId)
/*      */     throws ServiceException
/*      */   {
/*  692 */     this.cursor = new Cursor(null);
/*  693 */     this.cursor.itemId = new ItemId(el.getAttribute("id"), acctId);
/*  694 */     this.cursor.sortValue = el.getAttribute("sortVal", null);
/*  695 */     this.cursor.endSortValue = el.getAttribute("endSortVal", null);
/*  696 */     this.cursor.includeOffset = el.getAttributeBool("includeOffset", false);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public void parseCursor(CursorInfo cursorInfo, String acctId)
/*      */     throws ServiceException
/*      */   {
/*  706 */     this.cursor = new Cursor(null);
/*  707 */     if (null == cursorInfo.getId()) {
/*  708 */       throw ServiceException.INVALID_REQUEST("Invalid ID for cursor", null);
/*      */     }
/*  710 */     this.cursor.itemId = new ItemId(cursorInfo.getId(), acctId);
/*  711 */     this.cursor.sortValue = cursorInfo.getSortVal();
/*  712 */     this.cursor.endSortValue = cursorInfo.getEndSortVal();
/*  713 */     this.cursor.includeOffset = ((Boolean)Objects.firstNonNull(cursorInfo.getIncludeOffset(), Boolean.valueOf(false))).booleanValue();
/*      */   }
/*      */   
/*      */   private static TimeZone parseTimeZonePart(CalTZInfoInterface calTZ) throws ServiceException {
/*  717 */     String id = calTZ.getId();
/*      */     
/*      */ 
/*  720 */     ICalTimeZone knownTZ = WellKnownTimeZones.getTimeZoneById(id);
/*  721 */     if (knownTZ != null) {
/*  722 */       return knownTZ;
/*      */     }
/*      */     
/*      */ 
/*  726 */     return CalendarUtils.parseTimeZone(calTZ);
/*      */   }
/*      */   
/*      */   private static TimeZone parseTimeZonePart(Element tzElt) throws ServiceException {
/*  730 */     String id = tzElt.getAttribute("id");
/*      */     
/*      */ 
/*  733 */     ICalTimeZone knownTZ = WellKnownTimeZones.getTimeZoneById(id);
/*  734 */     if (knownTZ != null) {
/*  735 */       return knownTZ;
/*      */     }
/*      */     
/*      */ 
/*      */ 
/*  740 */     String test = tzElt.getAttribute("stdoff", null);
/*  741 */     if (test == null) {
/*  742 */       throw ServiceException.INVALID_REQUEST("Unknown TZ: \"" + id + "\" and no " + "stdoff" + " specified", null);
/*      */     }
/*      */     
/*      */ 
/*  746 */     return CalendarUtils.parseTzElement(tzElt);
/*      */   }
/*      */   
/*      */   static Locale parseLocale(String src) {
/*  750 */     if (Strings.isNullOrEmpty(src)) {
/*  751 */       return null;
/*      */     }
/*  753 */     Matcher matcher = LOCALE_PATTERN.matcher(src);
/*  754 */     if (matcher.lookingAt()) {
/*  755 */       String lang = null;
/*  756 */       String country = null;
/*  757 */       String variant = null;
/*  758 */       if (matcher.start(1) >= 0) {
/*  759 */         lang = matcher.group(1);
/*      */       }
/*      */       
/*  762 */       if (Strings.isNullOrEmpty(lang)) {
/*  763 */         return null;
/*      */       }
/*      */       
/*  766 */       if (matcher.start(2) >= 0) {
/*  767 */         country = matcher.group(2);
/*      */       }
/*      */       
/*  770 */       if (matcher.start(4) >= 0) {
/*  771 */         variant = matcher.group(4);
/*      */       }
/*      */       
/*  774 */       if (Strings.isNullOrEmpty(country))
/*  775 */         return new Locale(lang);
/*  776 */       if (Strings.isNullOrEmpty(variant)) {
/*  777 */         return new Locale(lang, country);
/*      */       }
/*  779 */       return new Locale(lang, country, variant);
/*      */     }
/*      */     
/*  782 */     return null;
/*      */   }
/*      */   
/*      */   private static int parseLimit(Integer limit) throws ServiceException {
/*  786 */     if ((null == limit) || (limit.intValue() <= 0))
/*  787 */       return 10;
/*  788 */     if (limit.intValue() > 1000) {
/*  789 */       return 1000;
/*      */     }
/*  791 */     return limit.intValue();
/*      */   }
/*      */   
/*      */   private static int parseLimit(Element request) throws ServiceException {
/*  795 */     return parseLimit(Integer.valueOf(request.getAttributeInt("limit", -1)));
/*      */   }
/*      */   
/*      */   public Object clone()
/*      */   {
/*  800 */     SearchParams result = new SearchParams();
/*  801 */     result.requestContext = this.requestContext;
/*  802 */     result.hopCount = this.hopCount;
/*  803 */     result.defaultField = this.defaultField;
/*  804 */     result.queryString = this.queryString;
/*  805 */     result.offset = this.offset;
/*  806 */     result.limit = this.limit;
/*  807 */     result.inlineRule = this.inlineRule;
/*  808 */     result.maxInlinedLength = this.maxInlinedLength;
/*  809 */     result.wantHtml = this.wantHtml;
/*  810 */     result.wantExpandGroupInfo = this.wantExpandGroupInfo;
/*  811 */     result.neuterImages = this.neuterImages;
/*  812 */     result.inlinedHeaders = this.inlinedHeaders;
/*  813 */     result.recipients = this.recipients;
/*  814 */     result.calItemExpandStart = this.calItemExpandStart;
/*  815 */     result.calItemExpandEnd = this.calItemExpandEnd;
/*  816 */     result.includeTagDeleted = this.includeTagDeleted;
/*  817 */     result.includeTagMuted = this.includeTagMuted;
/*  818 */     result.timezone = this.timezone;
/*  819 */     result.locale = this.locale;
/*  820 */     result.sortBy = this.sortBy;
/*  821 */     result.types = this.types;
/*  822 */     result.prefetch = this.prefetch;
/*  823 */     result.fetch = this.fetch;
/*  824 */     if (this.allowableTaskStatuses != null) {
/*  825 */       result.allowableTaskStatuses = new HashSet(this.allowableTaskStatuses);
/*      */     }
/*  827 */     if (this.cursor != null) {
/*  828 */       result.cursor = new Cursor(this.cursor, null);
/*      */     }
/*  830 */     result.inDumpster = this.inDumpster;
/*  831 */     return result;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static final class ExpandResults
/*      */   {
/*  838 */     public static final ExpandResults NONE = new ExpandResults("none");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  843 */     public static final ExpandResults FIRST = new ExpandResults("first");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  848 */     public static final ExpandResults UNREAD = new ExpandResults("unread");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  853 */     public static final ExpandResults UNREAD_FIRST = new ExpandResults("unread-first");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  858 */     public static final ExpandResults HITS = new ExpandResults("hits");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  863 */     public static final ExpandResults ALL = new ExpandResults("all");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  868 */     public static final ExpandResults FIRST_MSG = new ExpandResults("first-msg");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  873 */     public static final ExpandResults HITS_OR_FIRST_MSG = new ExpandResults("hits!");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  880 */     public static final ExpandResults U_OR_FIRST_MSG = new ExpandResults("u!");
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  886 */     public static final ExpandResults U1_OR_FIRST_MSG = new ExpandResults("u1!");
/*      */     
/*  888 */     private static final Map<String, ExpandResults> MAP = ImmutableMap.builder().put(NONE.name, NONE).put("0", NONE).put("false", NONE).put(FIRST.name, FIRST).put("1", FIRST).put(UNREAD.name, UNREAD).put("u", UNREAD).put(UNREAD_FIRST.name, UNREAD_FIRST).put("u1", UNREAD_FIRST).put(HITS.name, HITS).put(ALL.name, ALL).put(FIRST_MSG.name, FIRST_MSG).put("!", FIRST_MSG).put(HITS_OR_FIRST_MSG.name, HITS_OR_FIRST_MSG).put(U_OR_FIRST_MSG.name, U_OR_FIRST_MSG).put(U1_OR_FIRST_MSG.name, U1_OR_FIRST_MSG).put("u!1", U1_OR_FIRST_MSG).build();
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */     private final String name;
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */     private List<ItemId> itemIds;
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */     private ExpandResults(String name)
/*      */     {
/*  905 */       this.name = name;
/*      */     }
/*      */     
/*      */     private ExpandResults(String name, List<ItemId> ids)
/*      */     {
/*  910 */       this.name = name;
/*  911 */       this.itemIds = ids;
/*      */     }
/*      */     
/*  914 */     public boolean matches(MailItem item) { return (this.itemIds != null) && (item != null) && (matches(new ItemId(item))); }
/*      */     
/*      */     public boolean matches(ItemId id)
/*      */     {
/*  918 */       return (this.itemIds != null) && (this.itemIds.contains(id));
/*      */     }
/*      */     
/*      */     public static ExpandResults valueOf(String value, ZimbraSoapContext zsc) throws ServiceException {
/*  922 */       if (value == null) {
/*  923 */         return NONE;
/*      */       }
/*  925 */       value = value.toLowerCase();
/*  926 */       ExpandResults result = (ExpandResults)MAP.get(value);
/*  927 */       if (result != null) {
/*  928 */         return result;
/*      */       }
/*      */       try {
/*  931 */         String[] split = value.split(",");
/*  932 */         ArrayList<ItemId> itemIds = new ArrayList();
/*  933 */         for (int i = 0; i < split.length; i++) {
/*  934 */           itemIds.add(new ItemId(split[i], zsc));
/*      */         }
/*  936 */         return new ExpandResults(value, itemIds);
/*      */       } catch (Exception e) {
/*  938 */         throw ServiceException.INVALID_REQUEST("invalid 'fetch' value: " + value, null);
/*      */       }
/*      */     }
/*      */     
/*      */     public String toString()
/*      */     {
/*  944 */       return this.name;
/*      */     }
/*      */     
/*  947 */     private static final Map<String, ExpandResults> LEGACY_MAP = ImmutableMap.builder().put(FIRST.name, FIRST).put("1", FIRST).put(HITS.name, HITS).put(ALL.name, ALL).build();
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */     public ExpandResults toLegacyExpandResults(Server server)
/*      */     {
/*  954 */       if ((server != null) && (server.getServerVersion() == null)) {
/*  955 */         if (LEGACY_MAP.containsKey(this.name)) {
/*  956 */           return this;
/*      */         }
/*      */         
/*      */ 
/*  960 */         ExpandResults mapped = ALL;
/*  961 */         if ((this == FIRST_MSG) || (this == U_OR_FIRST_MSG) || (this == U1_OR_FIRST_MSG)) {
/*  962 */           mapped = FIRST;
/*  963 */         } else if (this == HITS_OR_FIRST_MSG) {
/*  964 */           mapped = HITS;
/*      */         }
/*  966 */         ZimbraLog.search.debug("mapped current ExpandResults %s to %s for legacy server %s", new Object[] { this, mapped, server.getName() });
/*  967 */         return mapped;
/*      */       }
/*      */       
/*      */ 
/*  971 */       return this;
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static final class Cursor
/*      */   {
/*      */     private ItemId itemId;
/*      */     
/*      */ 
/*      */     private String sortValue;
/*      */     
/*      */ 
/*      */     private String endSortValue;
/*      */     
/*  987 */     private boolean includeOffset = false;
/*      */     
/*      */     private Cursor() {}
/*      */     
/*      */     private Cursor(Cursor src)
/*      */     {
/*  993 */       this.itemId = src.itemId;
/*  994 */       this.sortValue = src.sortValue;
/*  995 */       this.endSortValue = src.endSortValue;
/*  996 */       this.includeOffset = src.includeOffset;
/*      */     }
/*      */     
/*      */     public ItemId getItemId() {
/* 1000 */       return this.itemId;
/*      */     }
/*      */     
/*      */     public String getSortValue() {
/* 1004 */       return this.sortValue;
/*      */     }
/*      */     
/*      */     public void setSortValue(String value) {
/* 1008 */       this.sortValue = value;
/*      */     }
/*      */     
/*      */     public String getEndSortValue() {
/* 1012 */       return this.endSortValue;
/*      */     }
/*      */     
/*      */     public boolean isIncludeOffset() {
/* 1016 */       return this.includeOffset;
/*      */     }
/*      */   }
/*      */   
/*      */   public static enum Fetch
/*      */   {
/* 1022 */     NORMAL, 
/*      */     
/* 1024 */     IMAP, 
/*      */     
/* 1026 */     MODSEQ, 
/*      */     
/* 1028 */     PARENT, 
/*      */     
/* 1030 */     IDS;
/*      */     
/*      */     private Fetch() {}
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/index/SearchParams.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */